home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / pvm34b3.zip / pvm34b3 / pvm3 / tracer / trcutil.c < prev   
C/C++ Source or Header  |  1997-07-22  |  46KB  |  3,067 lines

  1.  
  2. static char rcsid[] = 
  3.     "$Id: trcutil.c,v 4.7 1997/06/25 21:46:07 pvmsrc Exp $";
  4.  
  5. /*
  6.  *         Tracer version 1.0:  A Trace File Generator for PVM
  7.  *           Oak Ridge National Laboratory, Oak Ridge TN.
  8.  *           Authors:  James Arthur Kohl and G. A. Geist
  9.  *                   (C) 1994 All Rights Reserved
  10.  *
  11.  *                              NOTICE
  12.  *
  13.  * Permission to use, copy, modify, and distribute this software and
  14.  * its documentation for any purpose and without fee is hereby granted
  15.  * provided that the above copyright notice appear in all copies and
  16.  * that both the copyright notice and this permission notice appear
  17.  * in supporting documentation.
  18.  *
  19.  * Neither the Institution, Oak Ridge National Laboratory, nor the
  20.  * Authors make any representations about the suitability of this
  21.  * software for any purpose.  This software is provided ``as is''
  22.  * without express or implied warranty.
  23.  *
  24.  * Tracer was funded by the U.S. Department of Energy.
  25.  */
  26.  
  27.  
  28. #include "trclib.h"
  29.  
  30. #ifdef WIN32
  31. #include <winsock.h>
  32. #endif
  33.  
  34.  
  35. extern struct Pvmtevinfo pvmtevinfo[];
  36.  
  37.  
  38. void
  39. trc_tracer_init()
  40. {
  41.     char hname[1024];
  42.  
  43.     /* Host Name */
  44.  
  45.     TRC_HOST_ALIAS = (char *) NULL;
  46.  
  47.     TRC_HOST_NAME = (char *) NULL;
  48.  
  49.     if ( gethostname( hname, 1023 ) == -1 )
  50.         perror( "Getting Hostname" );
  51.  
  52.     else
  53.     {
  54.         TRC_HOST_NAME = trc_copy_str( hname );
  55.  
  56.         TRC_HOST_ALIAS = trc_host_alias_str( TRC_HOST_NAME );
  57.     }
  58.  
  59.     /* TRC_DID Semantic Identifier List */
  60.  
  61.     TRC_DID_LIST = (TRC_DID) NULL;
  62.  
  63.     /* Tracer ID List */
  64.  
  65.     TRC_DEAD_ID_LIST = (TRC_ID) NULL;
  66.  
  67.     TRC_ID_LIST = (TRC_ID) NULL;
  68.  
  69.     /* TEV Descriptor List */
  70.  
  71.     TRC_TEVDESC_LIST = (TRC_TEVDESC *) NULL;
  72.  
  73.     TRC_TEVDESC_SIZE = -1;
  74.  
  75.     /* Set Up Semantic Identifier Lookup Trie */
  76.  
  77.     trc_init_did_trie();
  78.  
  79.     /* Initialize Event Processing Tries */
  80.  
  81.     TRC_HANDLE_TRIE = trc_create_triestack();
  82.  
  83.     TRC_EVENT_TRIE = trc_create_triestack();
  84.  
  85.     /* Define Special Event Descriptors */
  86.  
  87.     trc_define_special_descriptors();
  88.  
  89.     /* Initialize Time Vars */
  90.  
  91.     gettimeofday( &TRC_TRACE_TIME, (struct timezone *) NULL );
  92.  
  93.     /* Initialize Other Trace Globals */
  94.  
  95.     TRC_VERSION = (char *) NULL;
  96.  
  97.     TRC_NAME = (char *) NULL;
  98.  
  99.     TRC_HOST_ADD_NOTIFY_CODE = -1;
  100.     TRC_HOST_DEL_NOTIFY_CODE = -1;
  101.  
  102.     TRC_TID = -1;
  103.  
  104.     /* Initialize Old PVM 3.3 Trace Event Handling Stuff */
  105.  
  106.     trc_init_old_events();
  107. }
  108.  
  109.  
  110. TRC_ID
  111. trc_get_tracer_id()
  112. {
  113.     TRC_ID ID;
  114.  
  115.     ID = trc_create_tracer_id();
  116.  
  117.     /* Initialize Flags */
  118.  
  119.     ID->group_tasks = TRC_FALSE;
  120.  
  121.     /* Add to List */
  122.  
  123.     ID->next = TRC_ID_LIST;
  124.  
  125.     TRC_ID_LIST = ID;
  126.  
  127.     return( ID );
  128. }
  129.  
  130.  
  131. void
  132. trc_set_tracing_codes( ID )
  133. TRC_ID ID;
  134. {
  135. #ifndef USE_PVM_33
  136.     pvm_setopt( PvmTraceContext, ID->event_ctx );
  137. #endif
  138.     pvm_setopt( PvmTraceCode, ID->event_tag );
  139.     pvm_setopt( PvmTraceTid, TRC_TID );
  140.  
  141. #ifndef USE_PVM_33
  142.     pvm_setopt( PvmOutputContext, ID->output_ctx );
  143. #endif    
  144.     pvm_setopt( PvmOutputCode, ID->output_tag );
  145.     pvm_setopt( PvmOutputTid, TRC_TID );
  146. }
  147.  
  148.  
  149. int
  150. trc_set_trace_file( ID, trace_file )
  151. TRC_ID ID;
  152. char *trace_file;
  153. {
  154.     if ( trace_file != NULL )
  155.     {
  156.         if ( ID->trace_file != NULL )
  157.             free( ID->trace_file );
  158.         
  159.         ID->trace_file = trc_copy_str( trace_file );
  160.  
  161.         return( TRC_TRUE );
  162.     }
  163.  
  164.     else
  165.     {
  166.         trc_status_msg( ID, "Error: Null Trace File Name" );
  167.  
  168.         return( TRC_FALSE );
  169.     }
  170. }
  171.  
  172.  
  173. int
  174. trc_reset_trace_file( ID )
  175. TRC_ID ID;
  176. {
  177.     TRC_TEVDESC TD;
  178.  
  179.     int i;
  180.  
  181.     /* Close Any Existing Trace File */
  182.  
  183.     if ( ID->trace_out != NULL && ID->trace_out != stdout )
  184.         fclose( ID->trace_out );
  185.  
  186.     /* Clean Up Any Leftover Tasks */
  187.  
  188.     trc_free_tevtask_list( &(ID->tevtask_list) );
  189.  
  190.     /* Clean Up Any Dead Hosts */
  191.  
  192.     trc_cleanup_dead_hosts();
  193.  
  194.     /* Verify Trace File Set */
  195.  
  196.     if ( ID->trace_file == NULL )
  197.     {
  198.         trc_status_msg( ID, "Trace File Has Not Been Set." );
  199.  
  200.         return( TRC_FALSE );
  201.     }
  202.  
  203.     /* Open Trace File */
  204.  
  205.     if ( strcmp( ID->trace_file, "" ) )
  206.     {
  207.         ID->trace_out = fopen( ID->trace_file, "w" );
  208.  
  209.         if ( !trc_filecheck( ID->trace_out, ID->trace_file ) )
  210.             return( TRC_FALSE );
  211.     }
  212.  
  213.     else
  214.         ID->trace_out = stdout;
  215.  
  216.     /* Dump Initial Trace File Header */
  217.  
  218.     trc_dump_trace_header( ID );
  219.  
  220.     /* Reset Event Name Lookup Trie */
  221.  
  222.     trc_free_event_descriptors( TRC_EVENT_TRIE );
  223.  
  224.     trc_free_triestack( &TRC_EVENT_TRIE );
  225.  
  226.     TRC_EVENT_TRIE = trc_create_triestack();
  227.  
  228.     /* Reset System Trace Descriptors */
  229.  
  230.     for ( i=0 ; i < TRC_TEVDESC_SIZE ; i++ )
  231.     {
  232.         TD = TRC_TEVDESC_LIST[i];
  233.  
  234.         while ( TD != NULL )
  235.         {
  236.             TD->dump = TRC_TRUE;
  237.  
  238.             TD = TD->next;
  239.         }
  240.     }
  241.  
  242.     /* Reset Time Vars */
  243.  
  244.     gettimeofday( &TRC_TRACE_TIME, (struct timezone *) NULL );
  245.  
  246.     /* Reset Old PVM 3.3 Trace Descriptor Flags */
  247.  
  248.     trc_reset_old_descriptors();
  249.  
  250.     /* Set Trace File Complete Flag */
  251.  
  252.     ID->complete = TRC_FALSE;
  253.  
  254.     /* Successful Reset */
  255.  
  256.     return( TRC_TRUE );
  257. }
  258.  
  259.  
  260. int
  261. trc_set_output_file( ID, output_file )
  262. TRC_ID ID;
  263. char *output_file;
  264. {
  265.     if ( output_file != NULL )
  266.     {
  267.         if ( ID->output_file != NULL )
  268.             free( ID->output_file );
  269.         
  270.         ID->output_file = trc_copy_str( output_file );
  271.  
  272.         return( TRC_TRUE );
  273.     }
  274.  
  275.     else
  276.     {
  277.         trc_status_msg( ID, "Error: Null Output File Name" );
  278.  
  279.         return( TRC_FALSE );
  280.     }
  281. }
  282.  
  283.  
  284. int
  285. trc_open_output_file( ID )
  286. TRC_ID ID;
  287. {
  288.     /* Close Any Existing Output File */
  289.  
  290.     if ( ID->output_fp != NULL && ID->output_fp != stdout )
  291.         fclose( ID->output_fp );
  292.  
  293.     /* Verify Output File Set */
  294.  
  295.     if ( ID->output_file == NULL )
  296.     {
  297.         trc_status_msg( ID, "Output File Has Not Been Set." );
  298.  
  299.         return( TRC_FALSE );
  300.     }
  301.  
  302.     /* Open Output File */
  303.  
  304.     if ( strcmp( ID->output_file, "" ) )
  305.     {
  306.         ID->output_fp = fopen( ID->output_file, "w" );
  307.  
  308.         if ( !trc_filecheck( ID->output_fp, ID->output_file ) )
  309.             return( TRC_FALSE );
  310.     }
  311.  
  312.     else
  313.         ID->output_fp = stdout;
  314.  
  315.     /* Successful Opening */
  316.  
  317.     return( TRC_TRUE );
  318. }
  319.  
  320.  
  321. void
  322. trc_print_tmask( tmask )
  323. Pvmtmask tmask;
  324. {
  325.     static int indices[ TEV_MAX + 1 ];
  326.  
  327.     static int ncols = -1;
  328.     static int nrows = -1;
  329.     static int ntev = -1;
  330.  
  331.     static char fmt[64];
  332.  
  333.     int i, j, k;
  334.     int maxlen;
  335.     int width;
  336.     int index;
  337.     int flag;
  338.     int len;
  339.     int b;
  340.     int c;
  341.     int x;
  342.  
  343.     if ( ntev == -1 )
  344.     {
  345.         maxlen = -1;
  346.  
  347.         x = 0;
  348.  
  349.         for ( i=TEV_FIRST ; i <= TEV_MAX ; i++ )
  350.         {
  351.             /* Skip Internal Events */
  352.  
  353.             if ( strcmp( pvmtevinfo[i].name, "newtask" )
  354.                 && strcmp( pvmtevinfo[i].name, "spntask" )
  355.                 && strcmp( pvmtevinfo[i].name, "endtask" )
  356.                 && strcmp( pvmtevinfo[i].name, "timing" )
  357.                 && strcmp( pvmtevinfo[i].name, "profiling" ) )
  358.             {
  359.                 /* Determine Max Name Length */
  360.  
  361.                 len = strlen( pvmtevinfo[i].name );
  362.  
  363.                 if ( len > maxlen || maxlen == -1 )
  364.                     maxlen = len;
  365.  
  366.                 /* Sort 'Em Ugly Like */
  367.  
  368.                 flag = 0;
  369.  
  370.                 for ( j=0 ; j < x && !flag ; j++ )
  371.                 {
  372.                     if ( strcmp( pvmtevinfo[i].name,
  373.                         pvmtevinfo[ indices[j] ].name ) < 0 )
  374.                     {
  375.                         for ( k=x+1 ; k > j ; k-- )
  376.                             indices[k] = indices[k - 1];
  377.  
  378.                         indices[j] = i;
  379.  
  380.                         x++;
  381.  
  382.                         flag++;
  383.                     }
  384.                 }
  385.  
  386.                 if ( !flag )
  387.                     indices[x++] = i;
  388.             }
  389.         }
  390.  
  391.         ntev = x;
  392.  
  393.         maxlen += 4;
  394.  
  395.         ncols = 79 / maxlen;
  396.  
  397.         width = (79 / ncols) - 4;
  398.  
  399.         sprintf( fmt, " %%c %%-%ds%%c", width );
  400.  
  401.         nrows = ( ntev + ncols - 1 ) / ncols;
  402.     }
  403.  
  404.     for ( i=0 ; i < nrows ; i++ )
  405.     {
  406.         for ( c=0 ; c < ncols ; c++ )
  407.         {
  408.             index = i + (c * nrows);
  409.  
  410.             if ( index < ntev )
  411.             {
  412.                 x = indices[ index ];
  413.  
  414.                 b = TEV_MASK_CHECK( tmask, x );
  415.  
  416.                 printf( fmt, (b ? '*' : ' '), pvmtevinfo[x].name,
  417.                     (c == ncols - 1 ? '\n' : ' ') );
  418.             }
  419.  
  420.             else
  421.                 printf( "\n" );
  422.         }
  423.     }
  424. }
  425.  
  426.  
  427. TRC_TRIE
  428. trc_create_triestack()
  429. {
  430.     TRC_TRIE tptr;
  431.     TRC_TRIE tmp;
  432.  
  433.     int i;
  434.  
  435.     tmp = (TRC_TRIE) malloc( (unsigned) TRC_TRIE_SIZE
  436.         * sizeof( struct trc_trie_struct ) );
  437.     trc_memcheck( tmp, "Trie Structure" );
  438.  
  439.     for ( i=0 ; i < TRC_TRIE_SIZE ; i++ )
  440.     {
  441.         tptr = &(tmp[i]);
  442.  
  443.         tptr->valid = TRC_FALSE;
  444.  
  445.         tptr->str = (char *) NULL;
  446.  
  447.         tptr->value = (void *) NULL;
  448.  
  449.         tptr->next = (TRC_TRIE) NULL;
  450.     }
  451.  
  452.     return( tmp );
  453. }
  454.  
  455.  
  456. void
  457. trc_free_triestack( ptr )
  458. TRC_TRIE *ptr;
  459. {
  460.     TRC_TRIE T;
  461.     TRC_TRIE tptr;
  462.  
  463.     int i;
  464.  
  465.     if ( ptr == NULL || *ptr == NULL )
  466.         return;
  467.  
  468.     T = *ptr;
  469.  
  470.     for ( i=0 ; i < TRC_TRIE_SIZE ; i++ )
  471.     {
  472.         tptr = &(T[i]);
  473.  
  474.         tptr->valid = TRC_FALSE;
  475.  
  476.         if ( tptr->str != NULL )
  477.             free( tptr->str );
  478.  
  479.         tptr->str = (char *) NULL;
  480.  
  481.         tptr->value = (void *) NULL;
  482.  
  483.         if ( tptr->next != NULL )
  484.             trc_free_triestack( &(tptr->next) );
  485.     }
  486.  
  487.     free( T );
  488.  
  489.     *ptr = (TRC_TRIE) NULL;
  490. }
  491.  
  492.  
  493. int
  494. trc_add_to_trie( T, str, value )
  495. TRC_TRIE T;
  496. char *str;
  497. void *value;
  498. {
  499.     TRC_TRIE tptr;
  500.  
  501.     char *bump;
  502.  
  503.     int bumpindex;
  504.     int marked;
  505.     int index;
  506.     int len;
  507.     int i;
  508.  
  509.     if ( T == NULL )
  510.     {
  511.         printf( "\nError in trc_add_to_trie(): Null Trie\n\n" );
  512.  
  513.         return( TRC_FALSE );
  514.     }
  515.  
  516.     if ( str == NULL || !strcmp( str, "" ) )
  517.     {
  518.         printf( "\nError in trc_add_to_trie(): Empty String\n\n" );
  519.  
  520.         return( TRC_FALSE );
  521.     }
  522.  
  523.     len = strlen( str ) - 1;
  524.  
  525.     marked = 0;
  526.  
  527.     for ( i=0 ; i < len && !marked ; i++ )
  528.     {
  529.         index = trc_trie_index( str[i] );
  530.  
  531.         tptr = &(T[index]);
  532.  
  533.         if ( tptr->next != NULL )
  534.             T = tptr->next;
  535.  
  536.         else
  537.         {
  538.             if ( !tptr->valid )
  539.             {
  540.                 tptr->valid = TRC_TRUE;
  541.  
  542.                 tptr->str = trc_copy_str( str );
  543.  
  544.                 tptr->value = value;
  545.  
  546.                 marked++;
  547.             }
  548.  
  549.             else
  550.             {
  551.                 tptr->next = trc_create_triestack();
  552.  
  553.                 T = tptr->next;
  554.  
  555.                 bump = tptr->str;
  556.  
  557.                 if ( strlen( bump ) > i + 1 )
  558.                 {
  559.                     bumpindex = trc_trie_index( bump[ i + 1 ] );
  560.  
  561.                     T[bumpindex].valid = TRC_TRUE;
  562.                     T[bumpindex].str = bump;
  563.                     T[bumpindex].value = tptr->value;
  564.  
  565.                     tptr->valid = TRC_FALSE;
  566.                     tptr->str = (char *) NULL;
  567.                     tptr->value = (void *) NULL;
  568.                 }
  569.             }
  570.         }
  571.     }
  572.  
  573.     if ( !marked )
  574.     {
  575.         index = trc_trie_index( str[len] );
  576.  
  577.         tptr = &(T[index]);
  578.  
  579.         if ( tptr->valid )
  580.         {
  581.             bump = tptr->str;
  582.  
  583.             if ( strlen( bump ) > len + 1 )
  584.             {
  585.                 if ( tptr->next == NULL )
  586.                     tptr->next = trc_create_triestack();
  587.  
  588.                 T = tptr->next;
  589.  
  590.                 bumpindex = trc_trie_index( bump[ len + 1 ] );
  591.  
  592.                 T[bumpindex].valid = TRC_TRUE;
  593.                 T[bumpindex].str = bump;
  594.                 T[bumpindex].value = tptr->value;
  595.             }
  596.  
  597.             else
  598.             {
  599.                 printf( "\nError: Duplicate %s (%x)\n\n",
  600.                     bump, tptr->value );
  601.  
  602.                 return( TRC_FALSE );
  603.             }
  604.         }
  605.  
  606.         tptr->valid = TRC_TRUE;
  607.  
  608.         tptr->str = trc_copy_str( str );
  609.  
  610.         tptr->value = value;
  611.     }
  612.  
  613.     return( TRC_TRUE );
  614. }
  615.  
  616.  
  617. void *
  618. trc_lookup_trie( T, str )
  619. TRC_TRIE T;
  620. char *str;
  621. {
  622.     TRC_TRIE tptr;
  623.  
  624.     char *ptr;
  625.  
  626.     int len;
  627.     int i;
  628.  
  629.     len = strlen( str ) - 1;
  630.  
  631.     ptr = str;
  632.  
  633.     for ( i=0 ; i < len ; i++ )
  634.     {
  635.         tptr = &(T[ trc_trie_index( *ptr++ ) ]);
  636.  
  637.         if ( tptr->next != NULL )
  638.             T = tptr->next;
  639.  
  640.         else
  641.         {
  642.             if ( tptr->valid && !strcmp( tptr->str, str ) )
  643.                 return( tptr->value );
  644.  
  645.             else
  646.                 return( (void *) NULL );
  647.         }
  648.     }
  649.  
  650.     tptr = &(T[ trc_trie_index( *ptr ) ]);
  651.  
  652.     if ( tptr->valid && !strcmp( tptr->str, str ) )
  653.         return( tptr->value );
  654.  
  655.     else
  656.         return( (void *) NULL );
  657. }
  658.  
  659.  
  660. int
  661. trc_trie_index( c )
  662. char c;
  663. {
  664.     int index;
  665.  
  666.     if ( c >= 'a' && c <= 'z' )
  667.         index = (int) ( c - 'a' );
  668.  
  669.     else if ( c >= 'A' && c <= 'Z' )
  670.         index = (int) ( c - 'A' );
  671.     
  672.     else if ( c >= '0' && c <= '9' )
  673.         index = 26 + (int) ( c - '0' );
  674.  
  675.     else
  676.         index = TRC_TRIE_SIZE - 1;
  677.  
  678.     return( index );
  679. }
  680.  
  681.  
  682. TRC_DID
  683. trc_create_did()
  684. {
  685.     TRC_DID tmp;
  686.  
  687.     tmp = (TRC_DID) malloc( sizeof( struct trc_did_struct ) );
  688.     trc_memcheck( tmp, "Semantic Data ID Structure" );
  689.  
  690.     tmp->id = -1;
  691.  
  692.     tmp->name = (char *) NULL;
  693.  
  694.     tmp->desc = (char *) NULL;
  695.  
  696.     tmp->next = (TRC_DID) NULL;
  697.  
  698.     return( tmp );
  699. }
  700.  
  701.  
  702. void
  703. trc_free_did( ptr )
  704. TRC_DID *ptr;
  705. {
  706.     TRC_DID D;
  707.  
  708.     if ( ptr == NULL || *ptr == NULL )
  709.         return;
  710.  
  711.     D = *ptr;
  712.  
  713.     D->id = -1;
  714.  
  715.     if ( D->name != NULL )
  716.     {
  717.         free( D->name );
  718.  
  719.         D->name = (char *) NULL;
  720.     }
  721.  
  722.     if ( D->desc != NULL )
  723.     {
  724.         free( D->desc );
  725.  
  726.         D->desc = (char *) NULL;
  727.     }
  728.  
  729.     D->next = (TRC_DID) NULL;
  730.  
  731.     free( D );
  732.  
  733.     *ptr = (TRC_DID) NULL;
  734. }
  735.  
  736.  
  737. int
  738. trc_cmp_did( did1, did2 )
  739. TRC_DID did1;
  740. TRC_DID did2;
  741. {
  742.     if ( did1->id != did2->id )
  743.         return( TRC_FALSE );
  744.  
  745.     if ( strcmp( did1->name, did2->name ) )
  746.         return( TRC_FALSE );
  747.     
  748.     if ( strcmp( did1->desc, did2->desc ) )
  749.         return( TRC_FALSE );
  750.     
  751.     return( TRC_TRUE );
  752. }
  753.  
  754.  
  755. TRC_DATADESC
  756. trc_create_datadesc()
  757. {
  758.     TRC_DATADESC tmp;
  759.  
  760.     tmp = (TRC_DATADESC) malloc( sizeof( struct trc_datadesc_struct ) );
  761.     trc_memcheck( tmp, "Data Description Structure" );
  762.  
  763.     tmp->did = (TRC_DID) NULL;
  764.  
  765.     tmp->dt = -1;
  766.  
  767.     tmp->array = -1;
  768.  
  769.     tmp->data = (TRC_VALUE) NULL;
  770.  
  771.     tmp->num = -1;
  772.  
  773.     tmp->next = (TRC_DATADESC) NULL;
  774.  
  775.     return( tmp );
  776. }
  777.  
  778.  
  779. void
  780. trc_free_datadesc( ptr )
  781. TRC_DATADESC *ptr;
  782. {
  783.     TRC_DATADESC DD;
  784.  
  785.     if ( ptr == NULL || *ptr == NULL )
  786.         return;
  787.  
  788.     DD = *ptr;
  789.  
  790.     DD->did = (TRC_DID) NULL;
  791.  
  792.     DD->dt = -1;
  793.  
  794.     DD->array = -1;
  795.  
  796.     if ( DD->data != NULL )
  797.     {
  798.         free( DD->data );
  799.  
  800.         DD->data = (TRC_VALUE) NULL;
  801.     }
  802.  
  803.     DD->num = -1;
  804.  
  805.     DD->next = (TRC_DATADESC) NULL;
  806.  
  807.     free( DD );
  808.  
  809.     *ptr = (TRC_DATADESC) NULL;
  810. }
  811.  
  812.  
  813. int
  814. trc_cmp_datadesc( DD1, DD2 )
  815. TRC_DATADESC DD1;
  816. TRC_DATADESC DD2;
  817. {
  818.     TRC_DID D1, D2;
  819.  
  820.     D1 = DD1->did;
  821.     D2 = DD2->did;
  822.  
  823.     if ( D1 != NULL && D2 != NULL )
  824.     {
  825.         if ( !trc_cmp_did( DD1->did, DD2->did ) )
  826.             return( TRC_FALSE );
  827.     }
  828.  
  829.     else
  830.     {
  831.         if ( D1 != NULL || D2 != NULL )
  832.             return( TRC_FALSE );
  833.     }
  834.  
  835.     if ( DD1->dt != DD2->dt || DD1->array != DD2->array )
  836.         return( TRC_FALSE );
  837.  
  838.     return( TRC_TRUE );
  839. }
  840.  
  841.  
  842. int
  843. trc_get_dt_str( dtstr )
  844. char *dtstr;
  845. {
  846.     int i;
  847.  
  848.     for ( i=0 ; i < 16 ; i++ )
  849.     {
  850.         if ( !strcmp( TRC_TYPE_STRS[i], dtstr ) )
  851.             return( i );
  852.     }
  853.  
  854.     return( -1 );
  855. }
  856.  
  857.  
  858. TRC_TEVDESC
  859. trc_create_tevdesc()
  860. {
  861.     TRC_TEVDESC tmp;
  862.  
  863.     tmp = (TRC_TEVDESC) malloc( sizeof( struct trc_tevdesc_struct ) );
  864.     trc_memcheck( tmp, "Trace Event Descriptor Structure" );
  865.  
  866.     tmp->name = (char *) NULL;
  867.  
  868.     tmp->eid = -1;
  869.  
  870.     tmp->entry_exit = -1;
  871.  
  872.     tmp->index = -1;
  873.  
  874.     tmp->hid = -1;
  875.  
  876.     tmp->dump = -1;
  877.  
  878.     tmp->ddesc = (TRC_DATADESC) NULL;
  879.  
  880.     tmp->refcount = -1;
  881.  
  882.     tmp->next = (TRC_TEVDESC) NULL;
  883.  
  884.     return( tmp );
  885. }
  886.  
  887.  
  888. int
  889. trc_free_tevdesc( ptr )
  890. TRC_TEVDESC *ptr;
  891. {
  892.     TRC_TEVDESC TD;
  893.  
  894.     TRC_DATADESC DD;
  895.     TRC_DATADESC DDnext;
  896.  
  897.     if ( ptr == NULL || *ptr == NULL )
  898.         return( TRC_FALSE );
  899.  
  900.     TD = *ptr;
  901.  
  902.     (TD->refcount)--;
  903.  
  904.     if ( TD->refcount > 0 )
  905.         return( TRC_FALSE );
  906.  
  907.     if ( TD->name != NULL )
  908.         free( TD->name );
  909.  
  910.     TD->name = (char *) NULL;
  911.  
  912.     TD->eid = -1;
  913.  
  914.     TD->entry_exit = -1;
  915.  
  916.     TD->index = -1;
  917.  
  918.     TD->hid = -1;
  919.  
  920.     TD->dump = -1;
  921.  
  922.     DD = TD->ddesc;
  923.  
  924.     while ( DD != NULL )
  925.     {
  926.         DDnext = DD->next;
  927.  
  928.         trc_free_datadesc( &DD );
  929.  
  930.         DD = DDnext;
  931.     }
  932.  
  933.     TD->ddesc = (TRC_DATADESC) NULL;
  934.  
  935.     TD->refcount = -1;
  936.  
  937.     TD->next = (TRC_TEVDESC) NULL;
  938.  
  939.     free( TD );
  940.  
  941.     *ptr = (TRC_TEVDESC) NULL;
  942.  
  943.     return( TRC_TRUE );
  944. }
  945.  
  946.  
  947. int
  948. trc_cmp_tevdesc( TD1, TD2 )
  949. TRC_TEVDESC TD1;
  950. TRC_TEVDESC TD2;
  951. {
  952.     TRC_DATADESC DD1, DD2;
  953.  
  954.     if ( strcmp( TD1->name, TD2->name ) )
  955.         return( TRC_FALSE );
  956.  
  957.     if ( TD1->eid != TD2->eid || TD1->entry_exit != TD2->entry_exit )
  958.         return( TRC_FALSE );
  959.  
  960.     /* Ignore index & hid & dump */
  961.  
  962.     DD1 = TD1->ddesc;
  963.     DD2 = TD2->ddesc;
  964.  
  965.     while ( DD1 != NULL && DD2 != NULL )
  966.     {
  967.         if ( !trc_cmp_datadesc( DD1, DD2 ) )
  968.             return( TRC_FALSE );
  969.  
  970.         DD1 = DD1->next;
  971.         DD2 = DD2->next;
  972.     }
  973.  
  974.     if ( DD1 != NULL || DD2 != NULL )
  975.         return( TRC_FALSE );
  976.  
  977.     return( TRC_TRUE );
  978. }
  979.  
  980.  
  981. void
  982. trc_remove_tevdesc( ptr, index )
  983. TRC_TEVDESC *ptr;
  984. int index;
  985. {
  986.     TRC_TEVDESC TDnext;
  987.     TRC_TEVDESC TDlast;
  988.     TRC_TEVDESC TDptr;
  989.     TRC_TEVDESC TD;
  990.  
  991.     int eid;
  992.  
  993.     if ( ptr == NULL || *ptr == NULL )
  994.         return;
  995.  
  996.     /* Save Its Location */
  997.  
  998.     TD = *ptr;
  999.  
  1000.     TDnext = TD->next;
  1001.  
  1002.     /* Try To Free It */
  1003.  
  1004.     if ( trc_free_tevdesc( ptr ) )
  1005.     {
  1006.         /* Fix Up Descriptor List */
  1007.  
  1008.         eid = TRC_TEVEID_OF( index );
  1009.  
  1010.         TDptr = TRC_TEVDESC_LIST[ eid ];
  1011.  
  1012.         TDlast = (TRC_TEVDESC) NULL;
  1013.  
  1014.         while ( TDptr != NULL )
  1015.         {
  1016.             if ( TDptr == TD )
  1017.             {
  1018.                 if ( TDlast != NULL )
  1019.                     TDlast->next = TDnext;
  1020.  
  1021.                 else
  1022.                     TRC_TEVDESC_LIST[ eid ] = TDnext;
  1023.  
  1024.                 return;
  1025.             }
  1026.  
  1027.             else
  1028.             {
  1029.                 TDlast = TDptr;
  1030.  
  1031.                 TDptr = TDptr->next;
  1032.             }
  1033.         }
  1034.     }
  1035. }
  1036.  
  1037.  
  1038. void
  1039. trc_free_event_descriptors( T )
  1040. TRC_TRIE T;
  1041. {
  1042.     TRC_TRIE tptr;
  1043.  
  1044.     int i;
  1045.  
  1046.     if ( T == NULL )
  1047.         return;
  1048.  
  1049.     for ( i=0 ; i < TRC_TRIE_SIZE ; i++ )
  1050.     {
  1051.         tptr = &(T[i]);
  1052.  
  1053.         if ( tptr->value != NULL )
  1054.             trc_free_tevdesc( (TRC_TEVDESC *) &(tptr->value) );
  1055.  
  1056.         if ( tptr->next != NULL )
  1057.             trc_free_event_descriptors( tptr->next );
  1058.     }
  1059. }
  1060.  
  1061.  
  1062. TRC_TEVDESC_INFO
  1063. trc_create_tevdesc_info()
  1064. {
  1065.     TRC_TEVDESC_INFO tmp;
  1066.  
  1067.     tmp = (TRC_TEVDESC_INFO) malloc(
  1068.         sizeof( struct trc_tevdesc_info_struct ) );
  1069.     trc_memcheck( tmp, "Trace Event Descriptor Info Structure" );
  1070.  
  1071.     tmp->id = -1;
  1072.  
  1073.     tmp->dt = -1;
  1074.  
  1075.     tmp->array = -1;
  1076.  
  1077.     return( tmp );
  1078. }
  1079.  
  1080.  
  1081. void
  1082. trc_free_tevdesc_info( ptr )
  1083. TRC_TEVDESC_INFO *ptr;
  1084. {
  1085.     TRC_TEVDESC_INFO TI;
  1086.  
  1087.     if ( ptr == NULL || *ptr == NULL )
  1088.         return;
  1089.  
  1090.     TI = *ptr;
  1091.  
  1092.     TI->id = -1;
  1093.  
  1094.     TI->dt = -1;
  1095.  
  1096.     TI->array = -1;
  1097.  
  1098.     free( TI );
  1099.  
  1100.     *ptr = (TRC_TEVDESC_INFO) NULL;
  1101. }
  1102.  
  1103.  
  1104. TRC_TEVREC
  1105. trc_create_tevrec()
  1106. {
  1107.     TRC_TEVREC tmp;
  1108.  
  1109.     tmp = (TRC_TEVREC) malloc( sizeof( struct trc_tevrec_struct ) );
  1110.     trc_memcheck( tmp, "Trace Event Record Structure" );
  1111.  
  1112.     tmp->ddesc = (TRC_DATADESC) NULL;
  1113.  
  1114.     tmp->value = (TRC_VALUE) NULL;
  1115.  
  1116.     tmp->num = -1;
  1117.  
  1118.     tmp->next = (TRC_TEVREC) NULL;
  1119.  
  1120.     return( tmp );
  1121. }
  1122.  
  1123.  
  1124. void
  1125. trc_free_tevrec( ptr )
  1126. TRC_TEVREC *ptr;
  1127. {
  1128.     TRC_TEVREC TR;
  1129.  
  1130.     if ( ptr == NULL || *ptr == NULL )
  1131.         return;
  1132.  
  1133.     TR = *ptr;
  1134.  
  1135.     TR->ddesc = (TRC_DATADESC) NULL;
  1136.  
  1137.     if ( TR->value != NULL )
  1138.         free( TR->value );
  1139.     
  1140.     TR->value = (TRC_VALUE) NULL;
  1141.  
  1142.     TR->num = -1;
  1143.  
  1144.     if ( TR->next != NULL )
  1145.         trc_free_tevrec( &(TR->next) );
  1146.  
  1147.     free( *ptr );
  1148.  
  1149.     *ptr = (TRC_TEVREC) NULL;
  1150. }
  1151.  
  1152.  
  1153. TRC_TEVREC
  1154. trc_get_tevrec( TR, did )
  1155. TRC_TEVREC TR;
  1156. char *did;
  1157. {
  1158.     TRC_TEVREC trptr;
  1159.  
  1160.     trptr = TR;
  1161.  
  1162.     while ( trptr != NULL )
  1163.     {
  1164.         if ( !strcmp( did, trptr->ddesc->did->name ) )
  1165.             return( trptr );
  1166.  
  1167.         trptr = trptr->next;
  1168.     }
  1169.  
  1170.     return( trptr );
  1171. }
  1172.  
  1173.  
  1174. char *
  1175. trc_tevrec_string( TD, TR, tid, tsec, tusec )
  1176. TRC_TEVDESC TD;
  1177. TRC_TEVREC TR;
  1178. int tid;
  1179. int tsec;
  1180. int tusec;
  1181. {
  1182.     TRC_DATADESC DD;
  1183.  
  1184.     TRC_TEVREC trptr;
  1185.  
  1186.     char event_str[2048];
  1187.     char tmp[2048];
  1188.  
  1189.     char *tusec_pad;
  1190.     char *ptr;
  1191.  
  1192.     int first;
  1193.     int i;
  1194.  
  1195.     /* Dump Header Text */
  1196.  
  1197.     tusec_pad = trc_pad_num( tusec, 6 );
  1198.  
  1199.     if ( TD->entry_exit != TRC_IGNORE_TEV )
  1200.     {
  1201.         sprintf( event_str, "%s(%d.%d) @ %d.%s",
  1202.             TD->name, TD->entry_exit, TD->index, tsec, tusec_pad );
  1203.     }
  1204.  
  1205.     else
  1206.     {
  1207.         sprintf( event_str, "%s(%d) @ %d.%s",
  1208.             TD->name, TD->index, tsec, tusec_pad );
  1209.     }
  1210.  
  1211.     free( tusec_pad );
  1212.  
  1213.     /* Dump Event Data */
  1214.  
  1215.     first = TRC_TRUE;
  1216.  
  1217.     trptr = TR;
  1218.  
  1219.     while ( trptr != NULL )
  1220.     {
  1221.         DD = trptr->ddesc;
  1222.  
  1223.         /* Skip Over TS, TU, and TID */
  1224.  
  1225.         if ( strcmp( DD->did->name, "TS" )
  1226.             && strcmp( DD->did->name, "TU" )
  1227.             && strcmp( DD->did->name, "TID" ) )
  1228.         {
  1229.             /* Check for first data item -> put out : */
  1230.  
  1231.             if ( first )
  1232.             {
  1233.                 trc_append_str( event_str, ": ", 2048 );
  1234.  
  1235.                 first = TRC_FALSE;
  1236.             }
  1237.  
  1238.             /* Get Data Name */
  1239.  
  1240.             ptr = DD->did->name;
  1241.  
  1242.             i = 0;
  1243.  
  1244.             while ( *ptr != '\0' )
  1245.                 tmp[i++] = *ptr++;
  1246.  
  1247.             tmp[i++] = '=';
  1248.             tmp[i++] = '\0';
  1249.  
  1250.             trc_append_str( event_str, tmp, 2048 );
  1251.  
  1252.             /* Get Data Itself */
  1253.  
  1254.             switch( DD->dt )
  1255.             {
  1256.                 case TEV_DATA_NULL: break;
  1257.  
  1258.                 case TEV_DATA_BYTE:
  1259.                 {
  1260.                     sprintf( tmp, "{%s}", (char *) trptr->value );
  1261.  
  1262.                     trc_append_str( event_str, tmp, 2048 );
  1263.  
  1264.                     break;
  1265.                 }
  1266.  
  1267.                 case TEV_DATA_CPLX:
  1268.                 case TEV_DATA_FLOAT:
  1269.                 {
  1270.                     if ( trptr->num > 1 )
  1271.                     {
  1272.                         trc_append_str( event_str, "{ ", 2048 );
  1273.                     }
  1274.  
  1275.                     for ( i=0 ; i < trptr->num ; i++ )
  1276.                     {
  1277.                         if ( i < trptr->num - 1 )
  1278.                         {
  1279.                             sprintf( tmp, "%f, ", 
  1280.                                 TRC_ARR_VALUE_OF( trptr->value,
  1281.                                     float, i ) );
  1282.                         }
  1283.  
  1284.                         else
  1285.                         {
  1286.                             sprintf( tmp, "%f", 
  1287.                                 TRC_ARR_VALUE_OF( trptr->value,
  1288.                                     float, i ) );
  1289.                         }
  1290.  
  1291.                         trc_append_str( event_str, tmp, 2048 );
  1292.                     }
  1293.  
  1294.                     if ( trptr->num > 1 )
  1295.                         trc_append_str( event_str, " }", 2048 );
  1296.  
  1297.                     break;
  1298.                 }
  1299.  
  1300.                 case TEV_DATA_DCPLX:
  1301.                 case TEV_DATA_DOUBLE:
  1302.                 {
  1303.                     if ( trptr->num > 1 )
  1304.                         trc_append_str( event_str, "{ ", 2048 );
  1305.  
  1306.                     for ( i=0 ; i < trptr->num ; i++ )
  1307.                     {
  1308.                         if ( i < trptr->num - 1 )
  1309.                         {
  1310.                             sprintf( tmp, "%lf, ", 
  1311.                                 TRC_ARR_VALUE_OF( trptr->value,
  1312.                                     double, i ) );
  1313.                         }
  1314.  
  1315.                         else
  1316.                         {
  1317.                             sprintf( tmp, "%lf", 
  1318.                                 TRC_ARR_VALUE_OF( trptr->value,
  1319.                                     double, i ) );
  1320.                         }
  1321.  
  1322.                         trc_append_str( event_str, tmp, 2048 );
  1323.                     }
  1324.  
  1325.                     if ( trptr->num > 1 )
  1326.                         trc_append_str( event_str, " }", 2048 );
  1327.  
  1328.                     break;
  1329.                 }
  1330.  
  1331.                 case TEV_DATA_INT:
  1332.                 {
  1333.                     if ( trptr->num > 1 )
  1334.                         trc_append_str( event_str, "{ ", 2048 );
  1335.  
  1336.                     for ( i=0 ; i < trptr->num ; i++ )
  1337.                     {
  1338.                         if ( i < trptr->num - 1 )
  1339.                         {
  1340.                             sprintf( tmp, "%d, ", 
  1341.                                 TRC_ARR_VALUE_OF( trptr->value,
  1342.                                     int, i ) );
  1343.                         }
  1344.  
  1345.                         else
  1346.                         {
  1347.                             sprintf( tmp, "%d", 
  1348.                                 TRC_ARR_VALUE_OF( trptr->value,
  1349.                                     int, i ) );
  1350.                         }
  1351.  
  1352.                         trc_append_str( event_str, tmp, 2048 );
  1353.                     }
  1354.  
  1355.                     if ( trptr->num > 1 )
  1356.                         trc_append_str( event_str, " }", 2048 );
  1357.  
  1358.                     break;
  1359.                 }
  1360.  
  1361.                 case TEV_DATA_UINT:
  1362.                 {
  1363.                     if ( trptr->num > 1 )
  1364.                         trc_append_str( event_str, "{ ", 2048 );
  1365.  
  1366.                     for ( i=0 ; i < trptr->num ; i++ )
  1367.                     {
  1368.                         if ( i < trptr->num - 1 )
  1369.                         {
  1370.                             sprintf( tmp, "%u, ", 
  1371.                                 TRC_ARR_VALUE_OF( trptr->value,
  1372.                                     unsigned, i ) );
  1373.                         }
  1374.  
  1375.                         else
  1376.                         {
  1377.                             sprintf( tmp, "%u", 
  1378.                                 TRC_ARR_VALUE_OF( trptr->value,
  1379.                                     unsigned, i ) );
  1380.                         }
  1381.  
  1382.                         trc_append_str( event_str, tmp, 2048 );
  1383.                     }
  1384.  
  1385.                     if ( trptr->num > 1 )
  1386.                         trc_append_str( event_str, " }", 2048 );
  1387.  
  1388.                     break;
  1389.                 }
  1390.  
  1391.                 case TEV_DATA_LONG:
  1392.                 case TEV_DATA_ULONG:
  1393.                 {
  1394.                     if ( trptr->num > 1 )
  1395.                         trc_append_str( event_str, "{ ", 2048 );
  1396.  
  1397.                     for ( i=0 ; i < trptr->num ; i++ )
  1398.                     {
  1399.                         if ( i < trptr->num - 1 )
  1400.                         {
  1401.                             sprintf( tmp, "%ld, ", 
  1402.                                 TRC_ARR_VALUE_OF( trptr->value,
  1403.                                     long, i ) );
  1404.                         }
  1405.  
  1406.                         else
  1407.                         {
  1408.                             sprintf( tmp, "%ld", 
  1409.                                 TRC_ARR_VALUE_OF( trptr->value,
  1410.                                     long, i ) );
  1411.                         }
  1412.  
  1413.                         trc_append_str( event_str, tmp, 2048 );
  1414.                     }
  1415.  
  1416.                     if ( trptr->num > 1 )
  1417.                         trc_append_str( event_str, " }", 2048 );
  1418.  
  1419.                     break;
  1420.                 }
  1421.  
  1422.                 case TEV_DATA_SHORT:
  1423.                 {
  1424.                     if ( trptr->num > 1 )
  1425.                         trc_append_str( event_str, "{ ", 2048 );
  1426.  
  1427.                     for ( i=0 ; i < trptr->num ; i++ )
  1428.                     {
  1429.                         if ( i < trptr->num - 1 )
  1430.                         {
  1431.                             sprintf( tmp, "%d, ", 
  1432.                                 TRC_ARR_VALUE_OF( trptr->value,
  1433.                                     short, i ) );
  1434.                         }
  1435.  
  1436.                         else
  1437.                         {
  1438.                             sprintf( tmp, "%d", 
  1439.                                 TRC_ARR_VALUE_OF( trptr->value,
  1440.                                     short, i ) );
  1441.                         }
  1442.  
  1443.                         trc_append_str( event_str, tmp, 2048 );
  1444.                     }
  1445.  
  1446.                     if ( trptr->num > 1 )
  1447.                         trc_append_str( event_str, " }", 2048 );
  1448.  
  1449.                     break;
  1450.                 }
  1451.  
  1452.                 case TEV_DATA_USHORT:
  1453.                 {
  1454.                     if ( trptr->num > 1 )
  1455.                         trc_append_str( event_str, "{ ", 2048 );
  1456.  
  1457.                     for ( i=0 ; i < trptr->num ; i++ )
  1458.                     {
  1459.                         if ( i < trptr->num - 1 )
  1460.                         {
  1461.                             sprintf( tmp, "%d, ", 
  1462.                                 TRC_ARR_VALUE_OF( trptr->value,
  1463.                                     short, i ) );
  1464.                         }
  1465.  
  1466.                         else
  1467.                         {
  1468.                             sprintf( tmp, "%d", 
  1469.                                 TRC_ARR_VALUE_OF( trptr->value,
  1470.                                     short, i ) );
  1471.                         }
  1472.  
  1473.                         trc_append_str( event_str, tmp, 2048 );
  1474.                     }
  1475.  
  1476.                     if ( trptr->num > 1 )
  1477.                         trc_append_str( event_str, " }", 2048 );
  1478.  
  1479.                     break;
  1480.                 }
  1481.  
  1482.                 case TEV_DATA_STRING:
  1483.                 {
  1484.                     if ( trptr->num > 1 )
  1485.                         trc_append_str( event_str, "{ ", 2048 );
  1486.  
  1487.                     for ( i=0 ; i < trptr->num ; i++ )
  1488.                     {
  1489.                         if ( i < trptr->num - 1 )
  1490.                         {
  1491.                             sprintf( tmp, "{%s}, ",
  1492.                                 TRC_ARR_VALUE_OF( trptr->value,
  1493.                                     char *, i ) );
  1494.                         }
  1495.  
  1496.                         else
  1497.                         {
  1498.                             sprintf( tmp, "{%s}",
  1499.                                 TRC_ARR_VALUE_OF( trptr->value,
  1500.                                     char *, i ) );
  1501.                         }
  1502.  
  1503.                         trc_append_str( event_str, tmp, 2048 );
  1504.                     }
  1505.  
  1506.                     if ( trptr->num > 1 )
  1507.                         trc_append_str( event_str, " }", 2048 );
  1508.  
  1509.                     break;
  1510.                 }
  1511.  
  1512.                 case TEV_DATA_STRUCT_START:
  1513.                 case TEV_DATA_STRUCT_END:
  1514.                 case TEV_DATA_DEFERRED:
  1515.                 {
  1516.                     sprintf( tmp, "<DT Not Impl>" );
  1517.  
  1518.                     trc_append_str( event_str, tmp, 2048 );
  1519.                 }
  1520.  
  1521.                 default:
  1522.                 {
  1523.                     sprintf( tmp, "<DT Unknown>" );
  1524.  
  1525.                     trc_append_str( event_str, tmp, 2048 );
  1526.                 }
  1527.             }
  1528.  
  1529.             if ( trptr->next != NULL )
  1530.             {
  1531.                 sprintf( tmp, ", " );
  1532.  
  1533.                 trc_append_str( event_str, tmp, 2048 );
  1534.             }
  1535.         }
  1536.  
  1537.         trptr = trptr->next;
  1538.     }
  1539.  
  1540.     trc_append_str( event_str, ".", 2048 );
  1541.  
  1542.     return( trc_copy_str( event_str ) );
  1543. }
  1544.  
  1545.  
  1546. TRC_VALUE
  1547. trc_make_value( dt, num )
  1548. int dt;
  1549. int num;
  1550. {
  1551.     TRC_VALUE tmp;
  1552.  
  1553.     int i;
  1554.  
  1555.     if ( num < 1 )
  1556.         return( (TRC_VALUE) NULL );
  1557.  
  1558.     tmp = (TRC_VALUE) NULL;
  1559.  
  1560.     switch ( dt )
  1561.     {
  1562.         case TEV_DATA_NULL: break;
  1563.  
  1564.         case TEV_DATA_BYTE:
  1565.         {
  1566.             tmp = (TRC_VALUE) malloc( (unsigned) num * sizeof( char ) );
  1567.             trc_memcheck( tmp, "Character Data Pointer" );
  1568.  
  1569.             break;
  1570.         }
  1571.  
  1572.         case TEV_DATA_STRING:
  1573.         {
  1574.             tmp = (TRC_VALUE) malloc( (unsigned) num
  1575.                 * sizeof( char * ) );
  1576.             trc_memcheck( tmp, "String Data Pointer" );
  1577.  
  1578.             break;
  1579.         }
  1580.  
  1581.         case TEV_DATA_DCPLX:
  1582.         case TEV_DATA_DOUBLE:
  1583.         {
  1584.             tmp = (TRC_VALUE) malloc( (unsigned) num
  1585.                 * sizeof( double ) );
  1586.             trc_memcheck( tmp, "Double Data Pointer" );
  1587.  
  1588.             break;
  1589.         }
  1590.  
  1591.         case TEV_DATA_CPLX:
  1592.         case TEV_DATA_FLOAT:
  1593.         {
  1594.             tmp = (TRC_VALUE) malloc( (unsigned) num
  1595.                 * sizeof( float ) );
  1596.             trc_memcheck( tmp, "Float Data Pointer" );
  1597.  
  1598.             break;
  1599.         }
  1600.  
  1601.         case TEV_DATA_INT:
  1602.         case TEV_DATA_UINT:
  1603.         {
  1604.             tmp = (TRC_VALUE) malloc( (unsigned) num * sizeof( int ) );
  1605.             trc_memcheck( tmp, "Integer Data Pointer" );
  1606.  
  1607.             break;
  1608.         }
  1609.  
  1610.         case TEV_DATA_LONG:
  1611.         case TEV_DATA_ULONG:
  1612.         {
  1613.             tmp = (TRC_VALUE) malloc( (unsigned) num * sizeof( long ) );
  1614.             trc_memcheck( tmp, "Long Integer Data Pointer" );
  1615.  
  1616.             break;
  1617.         }
  1618.  
  1619.         case TEV_DATA_SHORT:
  1620.         case TEV_DATA_USHORT:
  1621.         {
  1622.             tmp = (TRC_VALUE) malloc( (unsigned) num
  1623.                 * sizeof( short ) );
  1624.             trc_memcheck( tmp, "Short Integer Data Pointer" );
  1625.  
  1626.             break;
  1627.         }
  1628.  
  1629.         case TEV_DATA_STRUCT_START:
  1630.         case TEV_DATA_STRUCT_END:
  1631.         case TEV_DATA_DEFERRED:
  1632.         {
  1633.             printf( "Value Data Type %d Not Implemented\n", dt );
  1634.  
  1635.             break;
  1636.         }
  1637.  
  1638.         default:
  1639.             printf( "Warning: Unknown Value Data Type %d\n", dt );
  1640.     }
  1641.  
  1642.     return( tmp );
  1643. }
  1644.  
  1645.  
  1646. TRC_VALUE
  1647. trc_copy_value( V, dt, num )
  1648. TRC_VALUE V;
  1649. int dt;
  1650. int num;
  1651. {
  1652.     TRC_VALUE tmp;
  1653.  
  1654.     int i;
  1655.  
  1656.     if ( V == NULL || num < 1 )
  1657.         return( (TRC_VALUE) NULL );
  1658.  
  1659.     tmp = (TRC_VALUE) NULL;
  1660.  
  1661.     switch ( dt )
  1662.     {
  1663.         case TEV_DATA_NULL: break;
  1664.  
  1665.         case TEV_DATA_BYTE:
  1666.         {
  1667.             tmp = (TRC_VALUE) malloc( (unsigned) num * sizeof( char ) );
  1668.             trc_memcheck( tmp, "Character Data Pointer" );
  1669.  
  1670.             for ( i=0 ; i < num ; i++ )
  1671.             {
  1672.                 TRC_ARR_VALUE_OF( tmp, char, i ) =
  1673.                     TRC_ARR_VALUE_OF( V, char, i );
  1674.             }
  1675.  
  1676.             break;
  1677.         }
  1678.  
  1679.         case TEV_DATA_STRING:
  1680.         {
  1681.             tmp = (TRC_VALUE) malloc( (unsigned) num
  1682.                 * sizeof( char * ) );
  1683.             trc_memcheck( tmp, "String Data Pointer" );
  1684.  
  1685.             for ( i=0 ; i < num ; i++ )
  1686.             {
  1687.                 TRC_ARR_VALUE_OF( tmp, char *, i ) =
  1688.                     trc_copy_str( TRC_ARR_VALUE_OF( V, char *, i ) );
  1689.             }
  1690.  
  1691.             break;
  1692.         }
  1693.  
  1694.         case TEV_DATA_DCPLX:
  1695.         case TEV_DATA_DOUBLE:
  1696.         {
  1697.             tmp = (TRC_VALUE) malloc( (unsigned) num
  1698.                 * sizeof( double ) );
  1699.             trc_memcheck( tmp, "Double Data Pointer" );
  1700.  
  1701.             for ( i=0 ; i < num ; i++ )
  1702.             {
  1703.                 TRC_ARR_VALUE_OF( tmp, double, i ) =
  1704.                     TRC_ARR_VALUE_OF( V, double, i );
  1705.             }
  1706.  
  1707.             break;
  1708.         }
  1709.  
  1710.         case TEV_DATA_CPLX:
  1711.         case TEV_DATA_FLOAT:
  1712.         {
  1713.             tmp = (TRC_VALUE) malloc( (unsigned) num
  1714.                 * sizeof( float ) );
  1715.             trc_memcheck( tmp, "Float Data Pointer" );
  1716.  
  1717.             for ( i=0 ; i < num ; i++ )
  1718.             {
  1719.                 TRC_ARR_VALUE_OF( tmp, float, i ) =
  1720.                     TRC_ARR_VALUE_OF( V, float, i );
  1721.             }
  1722.  
  1723.             break;
  1724.         }
  1725.  
  1726.         case TEV_DATA_INT:
  1727.         case TEV_DATA_UINT:
  1728.         {
  1729.             tmp = (TRC_VALUE) malloc( (unsigned) num * sizeof( int ) );
  1730.             trc_memcheck( tmp, "Integer Data Pointer" );
  1731.  
  1732.             for ( i=0 ; i < num ; i++ )
  1733.             {
  1734.                 TRC_ARR_VALUE_OF( tmp, int, i ) =
  1735.                     TRC_ARR_VALUE_OF( V, int, i );
  1736.             }
  1737.  
  1738.             break;
  1739.         }
  1740.  
  1741.         case TEV_DATA_LONG:
  1742.         case TEV_DATA_ULONG:
  1743.         {
  1744.             tmp = (TRC_VALUE) malloc( (unsigned) num * sizeof( long ) );
  1745.             trc_memcheck( tmp, "Long Integer Data Pointer" );
  1746.  
  1747.             for ( i=0 ; i < num ; i++ )
  1748.             {
  1749.                 TRC_ARR_VALUE_OF( tmp, long, i ) =
  1750.                     TRC_ARR_VALUE_OF( V, long, i );
  1751.             }
  1752.  
  1753.             break;
  1754.         }
  1755.  
  1756.         case TEV_DATA_SHORT:
  1757.         case TEV_DATA_USHORT:
  1758.         {
  1759.             tmp = (TRC_VALUE) malloc( (unsigned) num
  1760.                 * sizeof( short ) );
  1761.             trc_memcheck( tmp, "Short Integer Data Pointer" );
  1762.  
  1763.             for ( i=0 ; i < num ; i++ )
  1764.             {
  1765.                 TRC_ARR_VALUE_OF( tmp, short, i ) =
  1766.                     TRC_ARR_VALUE_OF( V, short, i );
  1767.             }
  1768.  
  1769.             break;
  1770.         }
  1771.  
  1772.         case TEV_DATA_STRUCT_START:
  1773.         case TEV_DATA_STRUCT_END:
  1774.         case TEV_DATA_DEFERRED:
  1775.         {
  1776.             printf( "Value Data Type %d Not Implemented\n", dt );
  1777.  
  1778.             break;
  1779.         }
  1780.  
  1781.         default:
  1782.             printf( "Warning: Unknown Value Data Type %d\n", dt );
  1783.     }
  1784.  
  1785.     return( tmp );
  1786. }
  1787.  
  1788.  
  1789. TRC_TEVTASK
  1790. trc_create_tevtask()
  1791. {
  1792.     TRC_TEVTASK tmp;
  1793.  
  1794.     tmp = (TRC_TEVTASK) malloc( sizeof( struct trc_tevtask_struct ) );
  1795.     trc_memcheck( tmp, "TEV Task Structure" );
  1796.  
  1797.     tmp->tid = -1;
  1798.  
  1799.     tmp->tevstatus = -1;
  1800.     tmp->outstatus = -1;
  1801.  
  1802.     tmp->tevlist = (void **) NULL;
  1803.     tmp->tevsize = -1;
  1804.  
  1805.     tmp->output = (char *) NULL;
  1806.  
  1807.     tmp->next = (TRC_TEVTASK) NULL;
  1808.  
  1809.     return( tmp );
  1810. }
  1811.  
  1812.  
  1813. void
  1814. trc_check_for_dead_host( ID, TT )
  1815. TRC_ID ID;
  1816. TRC_TEVTASK TT;
  1817. {
  1818.     TRC_TEVTASK TTptr;
  1819.  
  1820.     TRC_HOST Hlast;
  1821.     TRC_HOST H;
  1822.  
  1823.     int pvmd_tid;
  1824.     int alive;
  1825.     int tmp;
  1826.  
  1827.     /* Get Host Task ID, See if Host is "Dead" */
  1828.  
  1829.     pvmd_tid = pvm_tidtohost( TT->tid );
  1830.  
  1831.     H = trc_get_host_tid_last( pvmd_tid, &Hlast );
  1832.  
  1833.     if ( H->in_pvm != TRC_NOT_IN_PVM )
  1834.         return;
  1835.  
  1836.     /* Look for any living tasks on that host */
  1837.  
  1838.     TTptr = ID->tevtask_list;
  1839.  
  1840.     alive = 0;
  1841.  
  1842.     while ( TTptr != NULL && !alive )
  1843.     {
  1844.         tmp = pvm_tidtohost( TTptr->tid );
  1845.  
  1846.         if ( tmp == pvmd_tid
  1847.             && ( TTptr->tevstatus == TRC_TASK_ALIVE
  1848.                 || TTptr->outstatus == TRC_TASK_OUT ) )
  1849.         {
  1850.             alive++;
  1851.         }
  1852.  
  1853.         TTptr = TTptr->next;
  1854.     }
  1855.  
  1856.     /* Host can finally rest in peace... */
  1857.  
  1858.     if ( !alive )
  1859.     {
  1860.         if ( Hlast != NULL )
  1861.             Hlast->next = H->next;
  1862.         
  1863.         else
  1864.             TRC_HOST_LIST = H->next;
  1865.         
  1866.         trc_free_host( &H );
  1867.     }
  1868. }
  1869.  
  1870.  
  1871. void
  1872. trc_free_tevtask( ptr )
  1873. TRC_TEVTASK *ptr;
  1874. {
  1875.     TRC_TEVTASK TT;
  1876.  
  1877.     int i;
  1878.  
  1879.     if ( ptr == NULL || *ptr == NULL )
  1880.         return;
  1881.  
  1882.     TT = *ptr;
  1883.  
  1884.     TT->tid = -1;
  1885.  
  1886.     TT->tevstatus = -1;
  1887.     TT->outstatus = -1;
  1888.  
  1889.     if ( TT->tevlist != NULL )
  1890.     {
  1891.         for ( i=0 ; i < TT->tevsize ; i++ )
  1892.             TT->tevlist[i] = (void *) NULL;
  1893.  
  1894.         free( TT->tevlist );
  1895.  
  1896.         TT->tevlist = (void **) NULL;
  1897.     }
  1898.  
  1899.     TT->tevsize = -1;
  1900.  
  1901.     if ( TT->output != NULL )
  1902.     {
  1903.         free( TT->output );
  1904.  
  1905.         TT->output = (char *) NULL;
  1906.     }
  1907.  
  1908.     TT->next = (TRC_TEVTASK) NULL;
  1909.  
  1910.     free( TT );
  1911.  
  1912.     *ptr = (TRC_TEVTASK) NULL;
  1913. }
  1914.  
  1915.  
  1916. void
  1917. trc_free_tevtask_list( tevtask_list )
  1918. TRC_TEVTASK *tevtask_list;
  1919. {
  1920.     TRC_TEVTASK TTnext;
  1921.     TRC_TEVTASK TT;
  1922.  
  1923.     int i;
  1924.  
  1925.     TT = *tevtask_list;
  1926.  
  1927.     *tevtask_list = (TRC_TEVTASK) NULL;
  1928.  
  1929.     while ( TT != NULL )
  1930.     {
  1931.         /* Save Next Ptr */
  1932.  
  1933.         TTnext = TT->next;
  1934.  
  1935.         /* Wipe Out Traced Tasks */
  1936.  
  1937.         if ( TT->tevstatus == TRC_TASK_DEAD
  1938.             && TT->outstatus == TRC_TASK_EOF )
  1939.         {
  1940.             /* Wipe Out Associated Trace Event Descriptors */
  1941.  
  1942.             for ( i=0 ; i < TT->tevsize ; i++ )
  1943.             {
  1944.                 if ( TT->tevlist[i] != NULL )
  1945.                 {
  1946.                     trc_remove_tevdesc(
  1947.                         (TRC_TEVDESC *) &(TT->tevlist[i]), i );
  1948.                 }
  1949.             }
  1950.  
  1951.             /* Free Traced Task */
  1952.  
  1953.             trc_free_tevtask( &TT );
  1954.         }
  1955.  
  1956.         /* Save Leftover Tasks Still In Progress */
  1957.  
  1958.         else
  1959.         {
  1960.             /* Set Event and Output Status Flags */
  1961.  
  1962.             if ( TT->tevstatus != TRC_TASK_DEAD )
  1963.                 TT->tevstatus = TRC_TASK_WAITEND;
  1964.             
  1965.             if ( TT->outstatus != TRC_TASK_EOF )
  1966.                 TT->outstatus = TRC_TASK_WAITEOF;
  1967.  
  1968.             /* Add Back On List */
  1969.  
  1970.             TT->next = *tevtask_list;
  1971.  
  1972.             *tevtask_list = TT;
  1973.         }
  1974.  
  1975.         /* Next Task */
  1976.  
  1977.         TT = TTnext;
  1978.     }
  1979. }
  1980.  
  1981.  
  1982. TRC_TEVTASK
  1983. trc_get_tevtask_tid( ID, tid )
  1984. TRC_ID ID;
  1985. int tid;
  1986. {
  1987.     TRC_TEVTASK TT;
  1988.  
  1989.     TT = ID->tevtask_list;
  1990.  
  1991.     while ( TT != NULL )
  1992.     {
  1993.         if ( TT->tid == tid )
  1994.             return( TT );
  1995.  
  1996.         TT = TT->next;
  1997.     }
  1998.  
  1999.     return( (TRC_TEVTASK) NULL );
  2000. }
  2001.  
  2002.  
  2003. int
  2004. trc_tevtasks_alive( ID )
  2005. TRC_ID ID;
  2006. {
  2007.     TRC_TEVTASK TT;
  2008.  
  2009.     TT = ID->tevtask_list;
  2010.  
  2011.     while ( TT != NULL )
  2012.     {
  2013.         if ( TT->tevstatus == TRC_TASK_ALIVE
  2014.             || TT->outstatus == TRC_TASK_OUT )
  2015.         {
  2016.             return( TRC_TRUE );
  2017.         }
  2018.  
  2019.         TT = TT->next;
  2020.     }
  2021.  
  2022.     return( TRC_FALSE );
  2023. }
  2024.  
  2025.  
  2026. int
  2027. trc_tevtasks_dead( ID )
  2028. TRC_ID ID;
  2029. {
  2030.     TRC_TEVTASK TT;
  2031.  
  2032.     TT = ID->tevtask_list;
  2033.  
  2034.     while ( TT != NULL )
  2035.     {
  2036.         if ( TT->tevstatus != TRC_TASK_DEAD
  2037.             || TT->outstatus != TRC_TASK_EOF )
  2038.         {
  2039.             return( TRC_FALSE );
  2040.         }
  2041.  
  2042.         TT = TT->next;
  2043.     }
  2044.  
  2045.     return( TRC_TRUE );
  2046. }
  2047.  
  2048.  
  2049. void
  2050. trc_end_trace( ID )
  2051. TRC_ID ID;
  2052. {
  2053.     if ( ID->trace_out != NULL )
  2054.         trc_status_msg( ID, "Trace File Complete" );
  2055.  
  2056.     trc_free_tevtask_list( &(ID->tevtask_list) );
  2057.  
  2058.     trc_cleanup_dead_hosts();
  2059.  
  2060.     ID->complete = TRC_TRUE;
  2061. }
  2062.  
  2063.  
  2064. TRC_HOST
  2065. trc_create_host()
  2066. {
  2067.     TRC_HOST tmp;
  2068.  
  2069.     int i;
  2070.  
  2071.     tmp = (TRC_HOST) malloc( sizeof( struct trc_host_struct ) );
  2072.     trc_memcheck( tmp, "Host Structure" );
  2073.  
  2074.     tmp->name = (char *) NULL;
  2075.     tmp->alias = (char *) NULL;
  2076.     tmp->refname = (char *) NULL;
  2077.     tmp->arch = (char *) NULL;
  2078.  
  2079.     tmp->delta.tv_usec = 0;
  2080.     tmp->delta.tv_sec = 0;
  2081.  
  2082.     tmp->last_time.tv_usec = 0;
  2083.     tmp->last_time.tv_sec = 0;
  2084.  
  2085.     tmp->pvmd_tid = -1;
  2086.     tmp->speed = -1;
  2087.  
  2088.     /* Tracing Info */
  2089.  
  2090.     tmp->tevlist = (void **) NULL;
  2091.     tmp->tevsize = -1;
  2092.  
  2093.     tmp->didlist = (void **) NULL;
  2094.     tmp->didsize = -1;
  2095.  
  2096.     tmp->ext = (void *) NULL;
  2097.  
  2098.     tmp->next = (TRC_HOST) NULL;
  2099.  
  2100.     return( tmp );
  2101. }
  2102.  
  2103.  
  2104. void
  2105. trc_free_host( ptr )
  2106. TRC_HOST *ptr;
  2107. {
  2108.     TRC_HOST H;
  2109.  
  2110.     int i;
  2111.  
  2112.     if ( ptr == NULL || *ptr == NULL )
  2113.         return;
  2114.  
  2115.     H = *ptr;
  2116.  
  2117.     if ( H->name != NULL )
  2118.     {
  2119.         free( H->name );
  2120.  
  2121.         H->name = (char *) NULL;
  2122.     }
  2123.  
  2124.     if ( H->alias != NULL )
  2125.     {
  2126.         free( H->alias );
  2127.  
  2128.         H->alias = (char *) NULL;
  2129.     }
  2130.  
  2131.     if ( H->refname != NULL )
  2132.     {
  2133.         free( H->refname );
  2134.  
  2135.         H->refname = (char *) NULL;
  2136.     }
  2137.  
  2138.     if ( H->arch != NULL )
  2139.     {
  2140.         free( H->arch );
  2141.  
  2142.         H->arch = (char *) NULL;
  2143.     }
  2144.  
  2145.     H->delta.tv_usec = 0;
  2146.     H->delta.tv_sec = 0;
  2147.  
  2148.     H->last_time.tv_usec = 0;
  2149.     H->last_time.tv_sec = 0;
  2150.  
  2151.     H->pvmd_tid = -1;
  2152.     H->speed = -1;
  2153.  
  2154.     /* Tracing Info */
  2155.  
  2156.     if ( H->tevlist != NULL )
  2157.     {
  2158.         for ( i=0 ; i < H->tevsize ; i++ )
  2159.             H->tevlist[i] = (void *) NULL;
  2160.         
  2161.         free( H->tevlist );
  2162.  
  2163.         H->tevlist = (void **) NULL;
  2164.     }
  2165.  
  2166.     H->tevsize = -1;
  2167.  
  2168.     if ( H->didlist != NULL )
  2169.     {
  2170.         for ( i=0 ; i < H->didsize ; i++ )
  2171.             H->didlist[i] = (void *) NULL;
  2172.         
  2173.         free( H->didlist );
  2174.  
  2175.         H->didlist = (void **) NULL;
  2176.     }
  2177.  
  2178.     H->didsize = -1;
  2179.  
  2180.     H->ext = (void *) NULL;
  2181.  
  2182.     H->next = (TRC_HOST) NULL;
  2183.  
  2184.     free( H );
  2185.  
  2186.     *ptr = (TRC_HOST) NULL;
  2187. }
  2188.  
  2189.  
  2190. void
  2191. trc_cleanup_dead_hosts()
  2192. {
  2193.     TRC_HOST Hlast;
  2194.     TRC_HOST Hnext;
  2195.     TRC_HOST H;
  2196.  
  2197.     H = TRC_HOST_LIST;
  2198.  
  2199.     Hlast = (TRC_HOST) NULL;
  2200.  
  2201.     while ( H != NULL )
  2202.     {
  2203.         Hnext = H->next;
  2204.  
  2205.         if ( H->in_pvm == TRC_NOT_IN_PVM )
  2206.         {
  2207.             if ( Hlast != NULL )
  2208.                 Hlast->next = Hnext;
  2209.             
  2210.             else
  2211.                 TRC_HOST_LIST = Hnext;
  2212.             
  2213.             trc_free_host( &H );
  2214.         }
  2215.  
  2216.         else
  2217.             Hlast = H;
  2218.  
  2219.         H = Hnext;
  2220.     }
  2221. }
  2222.  
  2223.  
  2224. TRC_HOST
  2225. trc_get_host_name( name )
  2226. char *name;
  2227. {
  2228.     TRC_HOST H;
  2229.  
  2230.     H = TRC_HOST_LIST;
  2231.  
  2232.     while ( H != NULL )
  2233.     {
  2234.         if ( TRC_HOST_COMPARE( H, name ) )
  2235.             return( H );
  2236.  
  2237.         H = H->next;
  2238.     }
  2239.  
  2240.     return( (TRC_HOST) NULL );
  2241. }
  2242.  
  2243.  
  2244. TRC_HOST
  2245. trc_get_host_tid( tid )
  2246. int tid;
  2247. {
  2248.     TRC_HOST H;
  2249.  
  2250.     H = TRC_HOST_LIST;
  2251.  
  2252.     while ( H != NULL )
  2253.     {
  2254.         if ( H->pvmd_tid == tid )
  2255.             return( H );
  2256.  
  2257.         H = H->next;
  2258.     }
  2259.  
  2260.     return( (TRC_HOST) NULL );
  2261. }
  2262.  
  2263.  
  2264. TRC_HOST
  2265. trc_get_host_tid_last( tid, last )
  2266. int tid;
  2267. TRC_HOST *last;
  2268. {
  2269.     TRC_HOST H;
  2270.  
  2271.     H = TRC_HOST_LIST;
  2272.  
  2273.     *last = (TRC_HOST) NULL;
  2274.  
  2275.     while ( H != NULL )
  2276.     {
  2277.         if ( H->pvmd_tid == tid )
  2278.             return( H );
  2279.  
  2280.         else
  2281.         {
  2282.             *last = H;
  2283.  
  2284.             H = H->next;
  2285.         }
  2286.     }
  2287.  
  2288.     return( (TRC_HOST) NULL );
  2289. }
  2290.  
  2291.  
  2292. int
  2293. trc_check_host_sync( ID )
  2294. TRC_ID ID;
  2295. {
  2296.  
  2297. #ifdef PIGS_FLY
  2298.  
  2299.     TRC_HOST H;
  2300.  
  2301.     int elapsed;
  2302.     int ecnt;
  2303.  
  2304.     H = TRC_HOST_LIST;
  2305.  
  2306.     ecnt = 0;
  2307.  
  2308.     while ( H != NULL )
  2309.     {
  2310.         if ( H->in_pvm == TRC_IN_PVM && !TRC_LOCALHOST( H->name ) )
  2311.         {
  2312.             elapsed = TRC_TIME_ELAPSED( H->last_time, TRC_TRACE_TIME );
  2313.  
  2314.             if ( elapsed > 10000000 )
  2315.                 ecnt += trc_do_host_sync( ID, H, TRC_TRUE );
  2316.         }
  2317.  
  2318.         H = H->next;
  2319.     }
  2320.  
  2321.     return( ecnt );
  2322.  
  2323. #else
  2324.  
  2325.     return( 0 );
  2326.  
  2327. #endif
  2328.  
  2329. }
  2330.  
  2331.  
  2332. int
  2333. trc_do_host_sync( ID, H, dump_event )
  2334. TRC_ID ID;
  2335. TRC_HOST H;
  2336. int dump_event;
  2337. {
  2338.     struct timeval delta;
  2339.     struct timeval avg;
  2340.     struct timeval hi;
  2341.     struct timeval lo;
  2342.  
  2343.     int hiset, loset;
  2344.     int force;
  2345.     int valid;
  2346.     int ecnt;
  2347.     int i;
  2348.  
  2349.     if ( trc_compare( "0x", H->name ) )
  2350.         return( 0 );
  2351.  
  2352.     force = TRC_FALSE;
  2353.  
  2354.     valid = TRC_TRUE;
  2355.  
  2356.     hiset = loset = 0;
  2357.  
  2358.     ecnt = 0;
  2359.  
  2360.     avg.tv_sec = 0;
  2361.     avg.tv_usec = 0;
  2362.  
  2363.     for ( i=0 ; i < 10 && valid ; i++ )
  2364.     {
  2365.         TRC_PVMCKERR( pvm_hostsync( H->pvmd_tid,
  2366.             (struct timeval *) NULL, &delta ),
  2367.             "Host Sync", valid = TRC_FALSE );
  2368.         
  2369.         if ( valid )
  2370.         {
  2371.             if ( TRC_TIME_COMPARE( delta, hi ) > 0 || !hiset )
  2372.             {
  2373.                 hi.tv_sec = delta.tv_sec;
  2374.                 hi.tv_usec = delta.tv_usec;
  2375.  
  2376.                 hiset++;
  2377.             }
  2378.             
  2379.             if ( TRC_TIME_COMPARE( delta, lo ) < 0 || !loset )
  2380.             {
  2381.                 lo.tv_sec = delta.tv_sec;
  2382.                 lo.tv_usec = delta.tv_usec;
  2383.  
  2384.                 loset++;
  2385.             }
  2386.  
  2387.             avg.tv_sec += delta.tv_sec;
  2388.             avg.tv_usec += delta.tv_usec;
  2389.         }
  2390.     }
  2391.  
  2392.     if ( valid )
  2393.     {
  2394.         if ( H->delta.tv_sec != 0 || H->delta.tv_usec != 0 )
  2395.             force = TRC_TRUE;
  2396.  
  2397.         avg.tv_sec -= hi.tv_sec + lo.tv_sec;
  2398.         avg.tv_usec -= hi.tv_usec + lo.tv_usec;
  2399.  
  2400.         avg.tv_sec /= 8;
  2401.         avg.tv_usec /= 8;
  2402.  
  2403.         H->delta.tv_sec = avg.tv_sec;
  2404.         H->delta.tv_usec = avg.tv_usec;
  2405.  
  2406.         if ( H->delta.tv_usec < 0 )
  2407.         {
  2408.             H->delta.tv_usec += 1000000;
  2409.  
  2410.             (H->delta.tv_sec)--;
  2411.         }
  2412.  
  2413.         if ( dump_event &&
  2414.             ( force || H->delta.tv_sec != 0 || H->delta.tv_usec != 0 ) )
  2415.         {
  2416.             trc_write_host_sync_event( ID, H );
  2417.  
  2418.             ecnt++;
  2419.         }
  2420.  
  2421.         else
  2422.         {
  2423.             H->last_time.tv_sec = TRC_TRACE_TIME.tv_sec;
  2424.             H->last_time.tv_usec = TRC_TRACE_TIME.tv_usec;
  2425.         }
  2426.     }
  2427.  
  2428.     return( ecnt );
  2429. }
  2430.  
  2431.  
  2432. TRC_ID
  2433. trc_create_tracer_id()
  2434. {
  2435.     TRC_ID tmp;
  2436.  
  2437.     tmp = (TRC_ID) malloc( sizeof( struct trc_id_struct ) );
  2438.     trc_memcheck( tmp, "Tracer ID Structure" );
  2439.  
  2440.     tmp->complete = -1;
  2441.  
  2442.     tmp->group_tasks = -1;
  2443.  
  2444.     tmp->event_ctx = -1;
  2445.     tmp->event_tag = -1;
  2446.  
  2447.     tmp->output_ctx = -1;
  2448.     tmp->output_tag = -1;
  2449.  
  2450.     tmp->tevtask_list = (TRC_TEVTASK) NULL;
  2451.  
  2452.     tmp->trace_file = (char *) NULL;
  2453.  
  2454.     tmp->trace_out = (FILE *) NULL;
  2455.  
  2456.     tmp->trace_in = (FILE *) NULL;
  2457.  
  2458.     tmp->output_file = (char *) NULL;
  2459.  
  2460.     tmp->output_fp = (FILE *) NULL;
  2461.  
  2462.     tmp->status_msg = (trc_vfp) NULL;
  2463.     tmp->event_dump_hdr = (trc_vfp) NULL;
  2464.     tmp->output_dump_hdr = (trc_vfp) NULL;
  2465.     tmp->handle_host_add_notify = (trc_vfp) NULL;
  2466.     tmp->handle_host_del_notify = (trc_vfp) NULL;
  2467.     tmp->handle_descriptor = (trc_vfp) NULL;
  2468.     tmp->handle_old_descriptor = (trc_vfp) NULL;
  2469.     tmp->handle_event = (trc_vfp) NULL;
  2470.     tmp->handle_old_event = (trc_vfp) NULL;
  2471.     tmp->handle_command = (trc_vfp) NULL;
  2472.     tmp->handle_comment = (trc_vfp) NULL;
  2473.  
  2474.     tmp->next = (TRC_ID) NULL;
  2475.  
  2476.     return( tmp );
  2477. }
  2478.  
  2479.  
  2480. void
  2481. trc_free_tracer_id( ptr )
  2482. TRC_ID *ptr;
  2483. {
  2484.     TRC_ID ID;
  2485.  
  2486.     if ( ptr == NULL || *ptr == NULL )
  2487.         return;
  2488.  
  2489.     ID = *ptr;
  2490.  
  2491.     if ( ID->tevtask_list != NULL )
  2492.     {
  2493.         trc_free_tevtask_list( &(ID->tevtask_list) );
  2494.  
  2495.         /* Still Some Unfinished Tasks - Save It */
  2496.  
  2497.         if ( ID->tevtask_list != NULL )
  2498.         {
  2499.             ID->next = TRC_DEAD_ID_LIST;
  2500.  
  2501.             TRC_DEAD_ID_LIST = ID;
  2502.  
  2503.             *ptr = (TRC_ID) NULL;
  2504.  
  2505.             return;
  2506.         }
  2507.     }
  2508.  
  2509.     ID->complete = -1;
  2510.  
  2511.     ID->group_tasks = -1;
  2512.  
  2513.     ID->event_ctx = -1;
  2514.     ID->event_tag = -1;
  2515.  
  2516.     ID->output_ctx = -1;
  2517.     ID->output_tag = -1;
  2518.  
  2519.     if ( ID->trace_file != NULL )
  2520.     {
  2521.         free( ID->trace_file );
  2522.  
  2523.         ID->trace_file = (char *) NULL;
  2524.     }
  2525.  
  2526.     if ( ID->trace_out != NULL )
  2527.     {
  2528.         if ( ID->trace_out != stdout )
  2529.             fclose( ID->trace_out );
  2530.  
  2531.         ID->trace_out = (FILE *) NULL;
  2532.     }
  2533.  
  2534.     if ( ID->trace_in != NULL )
  2535.     {
  2536.         if ( ID->trace_in != stdin )
  2537.             fclose( ID->trace_in );
  2538.  
  2539.         ID->trace_in = (FILE *) NULL;
  2540.     }
  2541.  
  2542.     if ( ID->output_file != NULL )
  2543.     {
  2544.         free( ID->output_file );
  2545.  
  2546.         ID->output_file = (char *) NULL;
  2547.     }
  2548.  
  2549.     if ( ID->output_fp != NULL )
  2550.     {
  2551.         if ( ID->output_fp != stdout )
  2552.             fclose( ID->output_fp );
  2553.  
  2554.         ID->output_fp = (FILE *) NULL;
  2555.     }
  2556.  
  2557.     ID->status_msg = (trc_vfp) NULL;
  2558.     ID->event_dump_hdr = (trc_vfp) NULL;
  2559.     ID->output_dump_hdr = (trc_vfp) NULL;
  2560.     ID->handle_host_add_notify = (trc_vfp) NULL;
  2561.     ID->handle_host_del_notify = (trc_vfp) NULL;
  2562.     ID->handle_descriptor = (trc_vfp) NULL;
  2563.     ID->handle_old_descriptor = (trc_vfp) NULL;
  2564.     ID->handle_event = (trc_vfp) NULL;
  2565.     ID->handle_old_event = (trc_vfp) NULL;
  2566.     ID->handle_command = (trc_vfp) NULL;
  2567.     ID->handle_comment = (trc_vfp) NULL;
  2568.  
  2569.     ID->next = (TRC_ID) NULL;
  2570.  
  2571.     free( ID );
  2572.  
  2573.     *ptr = (TRC_ID) NULL;
  2574. }
  2575.  
  2576.  
  2577. void
  2578. trc_initialize_hosts( ID )
  2579. TRC_ID ID;
  2580. {
  2581.     TRC_HOST H;
  2582.  
  2583.     struct pvmhostinfo *hostp;
  2584.  
  2585.     int narch;
  2586.     int nhost;
  2587.     int host;
  2588.     int i, j;
  2589.     int new;
  2590.  
  2591.     /* Set Up Host Add Notifies */
  2592.  
  2593.     pvm_notify( PvmHostAdd, TRC_HOST_ADD_NOTIFY_CODE, -1,
  2594.         (int *) NULL );
  2595.  
  2596.     /* Get Existing Configuration */
  2597.  
  2598.     TRC_PVMCKERR( pvm_config( &nhost, &narch, &hostp ),
  2599.         "Error Checking Existing Configuration", exit( -1 ) );
  2600.  
  2601.     /* Set up Host Delete Notify's */
  2602.  
  2603.     for ( i=0 ; i < nhost ; i++ )
  2604.         pvm_notify( PvmHostDelete, 100, 1, &(hostp[i].hi_tid) );
  2605.  
  2606.     /* Process Hosts */
  2607.  
  2608.     for ( i=0 ; i < nhost ; i++ )
  2609.     {
  2610.         new = trc_update_host( &H, hostp, i, -1 );
  2611.  
  2612.         /* Invoke User Custom Handler */
  2613.  
  2614.         if ( new && ID != NULL && ID->handle_host_add_notify )
  2615.             (ID->handle_host_add_notify)( H );
  2616.     }
  2617.  
  2618.     /* Fix TRC_LOCALHOST / TRC_HOST_NAME - Network Name in use... */
  2619.  
  2620.     host = pvm_tidtohost( TRC_TID );
  2621.  
  2622.     H = trc_get_host_tid( host );
  2623.  
  2624.     if ( H != NULL )
  2625.     {
  2626.         if ( TRC_HOST_NAME != NULL )
  2627.             free( TRC_HOST_NAME );
  2628.  
  2629.         TRC_HOST_NAME = trc_copy_str( H->name );
  2630.  
  2631.         if ( TRC_HOST_ALIAS != NULL )
  2632.             free( TRC_HOST_ALIAS );
  2633.  
  2634.         TRC_HOST_ALIAS = trc_copy_str( H->alias );
  2635.  
  2636.         /* Verify Host Delay Cleared */
  2637.  
  2638.         H->delta.tv_sec = H->delta.tv_usec = 0;
  2639.     }
  2640. }
  2641.  
  2642.  
  2643. int
  2644. trc_handle_host_add_notify( ID, tids, num )
  2645. TRC_ID ID;
  2646. int *tids;
  2647. int num;
  2648. {
  2649.     TRC_HOST H;
  2650.  
  2651.     struct pvmhostinfo *hostp;
  2652.  
  2653.     int found;
  2654.     int narch;
  2655.     int nhost;
  2656.     int ecnt;
  2657.     int i, j;
  2658.     int new;
  2659.  
  2660.     ecnt = 0;
  2661.  
  2662.     TRC_PVMCKERR( pvm_config( &nhost, &narch, &hostp ),
  2663.         "Error Checking Existing Configuration", exit( -1 ) );
  2664.  
  2665.     /* Look For New Hosts */
  2666.  
  2667.     for ( i=0 ; i < num ; i++ )
  2668.     {
  2669.         /* Find Hostinfo Struct */
  2670.  
  2671.         found = -1;
  2672.  
  2673.         for ( j=0 ; j < nhost && found < 0 ; j++ )
  2674.         {
  2675.             if ( hostp[j].hi_tid == tids[i] )
  2676.                 found = j;
  2677.         }
  2678.  
  2679.         new = trc_update_host( &H, hostp, found, tids[i] );
  2680.  
  2681.         if ( new )
  2682.         {
  2683.             /* Invoke User Custom Handler */
  2684.  
  2685.             if ( ID->handle_host_add_notify )
  2686.                 (ID->handle_host_add_notify)( H );
  2687.  
  2688.             /* Save Host Add Event to Trace File */
  2689.  
  2690.             if ( ID->trace_out != NULL )
  2691.             {
  2692.                 trc_update_trace_time( -1, -1 );
  2693.  
  2694.                 trc_write_host_add_event( ID, H );
  2695.  
  2696.                 ecnt++;
  2697.  
  2698.                 if ( H->delta.tv_sec != 0 || H->delta.tv_usec != 0 )
  2699.                 {
  2700.                     trc_write_host_sync_event( ID, H );
  2701.  
  2702.                     ecnt++;
  2703.                 }
  2704.             }
  2705.         }
  2706.     }
  2707.  
  2708.     return( ecnt );
  2709. }
  2710.  
  2711.  
  2712. int
  2713. trc_handle_host_del_notify( ID, tid )
  2714. TRC_ID ID;
  2715. int tid;
  2716. {
  2717.     TRC_HOST Hlast;
  2718.     TRC_HOST H;
  2719.  
  2720.     int ecnt;
  2721.  
  2722.     ecnt = 0;
  2723.  
  2724.     /* Lookup Dead Host */
  2725.  
  2726.     H = trc_get_host_tid_last( tid, &Hlast );
  2727.  
  2728.     if ( H != NULL )
  2729.     {
  2730.         /* Mark Host as Dead */
  2731.  
  2732.         H->in_pvm = TRC_NOT_IN_PVM;
  2733.  
  2734.         /* Invoke User Custom Handler */
  2735.  
  2736.         if ( ID->handle_host_del_notify )
  2737.             (ID->handle_host_del_notify)( H );
  2738.  
  2739.         /* Save Host Delete Event to Trace File */
  2740.  
  2741.         if ( ID->trace_out != NULL )
  2742.         {
  2743.             trc_update_trace_time( -1, -1 );
  2744.  
  2745.             trc_write_host_del_event( ID, H, tid );
  2746.  
  2747.             ecnt++;
  2748.         }
  2749.     }
  2750.  
  2751.     else
  2752.         printf( "Missing Host for Notify Delete, TID=0x%x\n", tid );
  2753.  
  2754.     return( ecnt );
  2755. }
  2756.  
  2757.  
  2758. int
  2759. trc_update_host( Hret, hostp, index, tid )
  2760. TRC_HOST *Hret;
  2761. struct pvmhostinfo *hostp;
  2762. int index;
  2763. int tid;
  2764. {
  2765.     TRC_HOST Hlast;
  2766.     TRC_HOST H;
  2767.  
  2768.     struct pvmhostinfo *HP;
  2769.  
  2770.     char tmp[1024];
  2771.     char tmp2[1024];
  2772.  
  2773.     int too_quick;
  2774.     int found;
  2775.     int i, j;
  2776.     int new;
  2777.  
  2778.     too_quick = 0;
  2779.  
  2780.     new = 0;
  2781.  
  2782.     if ( index >= 0 )
  2783.     {
  2784.         HP = &(hostp[index]);
  2785.  
  2786.         tid = HP->hi_tid;
  2787.     }
  2788.     
  2789.     else
  2790.         too_quick++;
  2791.  
  2792.     /* Check Host List */
  2793.  
  2794.     H = trc_get_host_tid_last( tid, &Hlast );
  2795.  
  2796.     /* Host Not Found, Add to Hosts List */
  2797.  
  2798.     if ( H == NULL )
  2799.     {
  2800.         if ( Hlast != NULL )
  2801.             H = Hlast->next = trc_create_host();
  2802.         
  2803.         else
  2804.             H = TRC_HOST_LIST = trc_create_host();
  2805.  
  2806.         if ( !too_quick )
  2807.         {
  2808.             H->name = trc_copy_str( HP->hi_name );
  2809.  
  2810.             H->alias = trc_host_alias_str( H->name );
  2811.  
  2812.             H->refname = trc_copy_str( HP->hi_name );
  2813.  
  2814.             H->arch = trc_copy_str( HP->hi_arch );
  2815.  
  2816.             H->pvmd_tid = HP->hi_tid;
  2817.  
  2818.             H->speed = HP->hi_speed;
  2819.         }
  2820.  
  2821.         else
  2822.         {
  2823.             sprintf( tmp, "0x%x", tid );
  2824.  
  2825.             H->name = trc_copy_str( tmp );
  2826.  
  2827.             H->alias = trc_copy_str( tmp );
  2828.  
  2829.             H->refname = trc_copy_str( "" );
  2830.  
  2831.             H->arch = trc_copy_str( "DUMMY" );
  2832.  
  2833.             H->pvmd_tid = tid;
  2834.  
  2835.             H->speed = 0;
  2836.         }
  2837.  
  2838.         new++;
  2839.     }
  2840.  
  2841.     H->in_pvm = TRC_IN_PVM;
  2842.  
  2843.     /* Set Host Delay */
  2844.  
  2845.     if ( !TRC_LOCALHOST( H->name ) )
  2846.         trc_do_host_sync( (TRC_ID) NULL, H, TRC_FALSE );
  2847.  
  2848.     *Hret = H;
  2849.  
  2850.     return( new );
  2851. }
  2852.  
  2853.  
  2854. void
  2855. trc_status_msg( ID, msg )
  2856. TRC_ID ID;
  2857. char *msg;
  2858. {
  2859.     if ( ID->status_msg )
  2860.         (ID->status_msg)( ID, msg );
  2861.     
  2862.     else
  2863.         fprintf( stderr, "%s\n", msg );
  2864. }
  2865.  
  2866.  
  2867. char *
  2868. trc_date_str()
  2869. {
  2870.     char tmp[255];
  2871.  
  2872.     char *result;
  2873.  
  2874.     time_t t;
  2875.  
  2876.     time( &t );
  2877.  
  2878.     sprintf( tmp, "%s", ctime( &t ) );
  2879.  
  2880.     result = tmp;
  2881.  
  2882.     while ( *result != '\n' && *result != '\0' )
  2883.         result++;
  2884.     
  2885.     *result = '\0';
  2886.  
  2887.     result = trc_copy_str( tmp );
  2888.  
  2889.     return( result );
  2890. }
  2891.  
  2892.  
  2893. int
  2894. trc_append_str( result, str, maxlen )
  2895. char *result;
  2896. char *str;
  2897. int maxlen;
  2898. {
  2899.     char *strcat();
  2900.  
  2901.     int rlen;
  2902.     int len;
  2903.     int rc;
  2904.     int i;
  2905.  
  2906.     rlen = strlen( result );
  2907.  
  2908.     len = rlen + strlen( str ) + 1;
  2909.  
  2910.     rc = TRC_TRUE;
  2911.  
  2912.     if ( len <= maxlen )
  2913.         strcat( result, str );
  2914.  
  2915.     else
  2916.     {
  2917.         i = rlen;
  2918.  
  2919.         while ( i < maxlen - 4 )
  2920.         {
  2921.             result[i] = str[ i - rlen ];
  2922.  
  2923.             i++;
  2924.         }
  2925.  
  2926.         sprintf( (char *) (result + (maxlen - 4)), "..." );
  2927.  
  2928.         rc = TRC_FALSE;
  2929.     }
  2930.  
  2931.     return( rc );
  2932. }
  2933.  
  2934.  
  2935. char *
  2936. trc_host_alias_str( name )
  2937. char *name;
  2938. {
  2939.     char *ptr;
  2940.     char *tmp;
  2941.  
  2942.     char c;
  2943.  
  2944.     if ( name == NULL )
  2945.         return( (char *) NULL );
  2946.  
  2947.     ptr = name;
  2948.  
  2949.     while ( *ptr != '\0' && *ptr != '.' )
  2950.         ptr++;
  2951.  
  2952.     if ( *ptr == '.' )
  2953.     {
  2954.         c = *ptr;
  2955.  
  2956.         *ptr = '\0';
  2957.  
  2958.         tmp = trc_copy_str( name );
  2959.  
  2960.         *ptr = c;
  2961.     }
  2962.  
  2963.     else
  2964.         tmp = trc_copy_str( name );
  2965.     
  2966.     return( tmp );
  2967. }
  2968.  
  2969.  
  2970. char *
  2971. trc_pad_num( num, max )
  2972. long num;
  2973. long max;
  2974. {
  2975.     char tmp[1024];
  2976.  
  2977.     char *ptr;
  2978.     char *str;
  2979.  
  2980.     int nd;
  2981.     int nz;
  2982.     int i;
  2983.  
  2984.     sprintf( tmp, "%ld", num );
  2985.  
  2986.     nd = strlen( tmp );
  2987.  
  2988.     nz = max - nd;
  2989.  
  2990.     str = (char *) malloc( (unsigned) (max + 1) * sizeof(char) );
  2991.     trc_memcheck( str, "Numerical Pad String" );
  2992.  
  2993.     ptr = str;
  2994.  
  2995.     for ( i=0 ; i < nz ; i++ )
  2996.         *ptr++ = '0';
  2997.  
  2998.     sprintf( (char *) (str + nz), "%ld", num );
  2999.  
  3000.     return( str );
  3001. }
  3002.  
  3003.  
  3004. char *
  3005. trc_copy_str( str )
  3006. char *str;
  3007. {
  3008.     char *tmp;
  3009.  
  3010.     tmp = (char *) malloc( (unsigned) (strlen(str) + 1)
  3011.         * sizeof(char) );
  3012.     trc_memcheck(tmp,"Copy String");
  3013.  
  3014.     strcpy( tmp, str );
  3015.  
  3016.     return( tmp );
  3017. }
  3018.  
  3019.  
  3020. int
  3021. trc_filecheck( fp, name )
  3022. FILE *fp;
  3023. char *name;
  3024. {
  3025.     if ( fp == NULL )
  3026.     {
  3027.         fprintf( stderr, "\nError Opening File \"%s\"\n\n", name );
  3028.  
  3029.         return( TRC_FALSE );
  3030.     }
  3031.  
  3032.     return( TRC_TRUE );
  3033. }
  3034.  
  3035.  
  3036. void
  3037. trc_memcheck( ptr, name )
  3038. void *ptr;
  3039. char *name;
  3040. {
  3041.     if ( ptr == NULL )
  3042.     {
  3043.         fprintf( stderr, "\nError Allocating Memory for \"%s\"\n\n",
  3044.             name );
  3045.  
  3046.         exit( -1 );
  3047.     }
  3048. }
  3049.  
  3050.  
  3051. int
  3052. trc_compare( x, y )
  3053. char *x;
  3054. char *y;
  3055. {
  3056.     while ( *x != '\0' )
  3057.     {
  3058.         if ( *x != *y )
  3059.             return( TRC_FALSE );
  3060.  
  3061.         x++; y++;
  3062.     }
  3063.  
  3064.     return( TRC_TRUE );
  3065. }
  3066.  
  3067.